package com.xpc.starter.handler;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import com.xpc.starter.annotation.DataPermission;
import com.xpc.starter.aspect.DataPermissionAspect;
import com.xpc.starter.service.DataPermissionService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.select.PlainSelect;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Component
public class DataPermissionHandler {

    @Resource
    public DataPermissionService dataPermissionService;

    /**
     * 获取数据权限 SQL 片段
     *
     * @param plainSelect  查询对象
     * @param whereSegment 查询条件片段
     */
    @SneakyThrows(Exception.class)
    public Expression getSqlSegment(PlainSelect plainSelect, String whereSegment) {
        // 待执行 SQL Where 条件表达式
        Expression where = plainSelect.getWhere();
        DataPermission dataPermission = DataPermissionAspect.threadLocalDataPermission.get();
        if (dataPermission == null) {
            return where;
        } else {
            String column = dataPermission.column(); // 过滤的权限字段
            if (CharSequenceUtil.isEmpty(column)) {
                // 过滤权限字段为空 不过滤数据
                return where;
            }
            String table = dataPermission.table(); // 过滤的表名称
            // in 表达式
            InExpression inExpression = new InExpression();
            if (CharSequenceUtil.isNotEmpty(table)) {
                inExpression.setLeftExpression(new Column(table + "." + column));
            } else {
                inExpression.setLeftExpression(new Column(column));
            }
            // 获取调用者要实现这个接口数据权限
            List<String> dataPermissions = this.dataPermissionService.getDataPermissions();
            ExpressionList list = new ExpressionList(
                    dataPermissions.stream().map(StringValue::new).collect(Collectors.toList())
            );
            inExpression.setRightItemsList(list);
            return ObjectUtil.isNull(where) ? inExpression : new AndExpression(where, inExpression);
        }
//        log.info("开始进行权限过滤,where: {},mappedStatementId: {}", where, whereSegment);
//        // aop拦截 存入线程中
//        Method method = DataPermissionAspect.threadLocal.get();
//        if (Objects.isNull(method)) {
//            return where;
//        }
//        log.info("当前的执行方法：" + method.getName());
//        DataPermission dataPermission = DataPermissionAspect.threadLocalDataPermission.get();
//        log.info("dataPermission = {}", dataPermission);
//        if (method.isAnnotationPresent(DataPermission.class)) {
//            DataPermission annotation = method.getAnnotation(DataPermission.class);
//            if (annotation == null) {
//                return where;
//            }
//            String column = annotation.column(); // 过滤的权限字段
//            if (CharSequenceUtil.isEmpty(column)) {
//                // 过滤权限字段为空 不过滤数据
//                return where;
//            }
//            String table = annotation.table(); // 过滤的权限字段表
//            // in 表达式
//            InExpression inExpression = new InExpression();
//            if (CharSequenceUtil.isNotEmpty(table)) {
//                inExpression.setLeftExpression(new Column(table + "." + column));
//            } else {
//                inExpression.setLeftExpression(new Column(column));
//            }
//            // 获取调用者要实现这个接口数据权限
//            List<String> dataPermissions = this.dataPermissionService.getDataPermissions();
//            ExpressionList list = new ExpressionList(
//                    dataPermissions.stream().map(StringValue::new).collect(Collectors.toList())
//            );
//            inExpression.setRightItemsList(list);
//            return new AndExpression(where, inExpression);
//        } else {
//            return where;
//        }
    }

}